package com.cqjtu.tto.service.impl;

import com.cqjtu.tto.dao.mapper.FileMapper;
import com.cqjtu.tto.dao.pojo.Files;
import com.cqjtu.tto.dao.pojo.SftpProperties;
import com.cqjtu.tto.service.FileService;
import com.cqjtu.tto.utils.NumUtil;
import com.cqjtu.tto.vo.Results;
import com.cqjtu.tto.vo.params.FileParam;
import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;


@Slf4j
@Service
public class FileServiceImpl implements FileService {

    @Autowired
    FileMapper fileMapper;

    @Autowired
    SftpProperties config;

    private static final String SESSION_CONFIG_STRICT_HOST_KEY_CHECKING = "StrictHostKeyChecking";

    @Override
    public Results uploadFile(FileParam fileParam, InputStream inputStream) throws Exception {
        String targetPath = fileParam.getPath();                         //获取文件路径
        String surfix = fileParam.getFileName().substring(0,fileParam.getFileName().lastIndexOf("."));
        String prefix = fileParam.getFileName().substring(fileParam.getFileName().lastIndexOf(".")+1);
        Files files = new Files(NumUtil.nextPkId(),fileParam.getFolderId(),
                surfix,null,fileParam.getUploaderId(),prefix,0);
        ChannelSftp sftp = this.createSftp();
        try {
            sftp.cd(targetPath);
            log.info("Change path to {}",targetPath);
//            int index = targetPath.lastIndexOf("/");
//            String fileDir = targetPath.substring(0, index);
//            String fileName = targetPath.substring(index + 1);
//            boolean dirs = this.createDirs(fileDir, sftp);                 //根据文件路径创建多级目录
//            if(!dirs){
//                log.error("Remote path error. path:{}", targetPath);
//                throw new Exception("Upload File failure");
//            }
            sftp.put(inputStream, fileParam.getFileName());
            fileMapper.insert(files);
            return Results.success("上传成功！");
        } catch (SftpException e) {
            log.error("Upload file failure. TargetPath: {}", targetPath, e);
            return Results.fail(-500,"上传失败！");
        } finally {
            this.disconnect(sftp);
        }
    }

    @Override
    public Results uploadFile(FileParam fileParam , File file) throws Exception {
        return this.uploadFile(fileParam,new FileInputStream(file));
    }

    //  创建sftp链接
    private ChannelSftp createSftp() throws Exception {
        JSch jSch = new JSch();
        log.info("Try to connect sftp["+config.getUsername()+"@"+config.getHost()+"],use password]"+config.getPassword()+"]");
        Session session = createSession(jSch, config.getHost(), config.getUsername(), config.getPort());
        session.setPassword(config.getPassword());
        session.connect(config.getSessionConnectTimeout());
        log.info("Session connected to {}.", config.getHost());
        Channel channel = session.openChannel(config.getProtocol());
        channel.connect(config.getChannelConnectedTimeout());
        log.info("Channel created to {}.", config.getHost());
        return (ChannelSftp) channel;
    }
    /**
     * 关闭连接
     *
     * @param sftp
     */
    private void disconnect(ChannelSftp sftp) {
        try {
            if (sftp != null) {
                if (sftp.isConnected()) {
                    sftp.disconnect();
                } else if (sftp.isClosed()) {
                    log.info("sftp is closed already");
                }
                if (null != sftp.getSession()) {
                    sftp.getSession().disconnect();
                }
            }
        } catch (JSchException e) {
            e.printStackTrace();
        }
    }

    private Session createSession(JSch jsch, String host, String username, Integer port) throws Exception{
        Session session = null;
        if (port <= 0) {
            session = jsch.getSession(username,host);
        }
        else {
            session = jsch.getSession(username,host,port);
        }
        if(session == null){
            throw new Exception(host+"session is null");
        }
        session.setConfig(SESSION_CONFIG_STRICT_HOST_KEY_CHECKING,config.getSessionStrictHostKeyChecking());
        return session;
    }

}
